﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Xml;

namespace VidoopSecure
{
    public class EnrollmentService : Service
    {
        /// <summary>
        /// Create a <see cref="VidoopSecure.EnrollmentService" /> object.
        /// </summary>
        /// <param name="manager">The <see cref="VidoopSecure.VSManager" /> 
        /// for performing operations.</param>
        /// <param name="site">The <see cref="VidoopSecure.Site" /> associated
        /// with the service.</param>
        /// <param name="apiBase">The base URL for the VidoopSecure web service.</param>
        public EnrollmentService(VSManager manager, Site site, string apiBase)
            : base(manager, site, apiBase)
        {
        }

        /// <summary>
        /// Get a <see cref="VidoopSecure.Category" /> or all available
        /// <see cref="VidoopSecure.Category" />s.
        /// </summary>
        /// <param name="id">A <see cref="VidoopSecure.Category" /> Id
        /// if a single <see cref="VidoopSecure.Category" /> is being
        /// requested. If <paramref name="id" /> is null or an empty
        /// string, all <see cref="VidoopSecure.Category" />s will be
        /// returned.</param>
        /// <returns></returns>
        public Category GetCategory(string id) 
        {
            if (string.IsNullOrEmpty(id))
                return null;

            string apiUrl = this.CreateRequestUrl("/categories/" + id);

            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "GET", null, null);
            if (proxy.StatusCode == (int)HttpStatusCode.OK)
            {
                Category category = Category.FromXml(proxy.Response.GetResponseStream());
                proxy.Close();
                return category;
            }
            else
            {
                proxy.Close();
                return null;
            }
        }

        /// <summary>
        /// Get a <see cref="System.Collections.Generic.List" /> of
        /// all <see cref="VidoopSecure.Category" />s.
        /// </summary>
        /// <returns>A <see cref="System.Collections.Generic.List" /> 
        /// containing all VidoopSecure categories.</returns>
        public List<Category> GetCategories()
        {
            string apiUrl = this.CreateRequestUrl("/categories");

            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "GET", null, null);
            if (proxy.StatusCode == (int)HttpStatusCode.OK)
            {
                List<Category> categories = Category.FromCategoriesXml(proxy.Response.GetResponseStream());
                proxy.Close();
                return categories;
            }
            else
            {
                proxy.Close();
                return null;
            }
        }

        /// <summary>
        /// Get representative images for the <see cref="VidoopSecure.Category" />
        /// identified by <paramref name="id" />.
        /// </summary>
        /// <param name="id">A <see cref="VidoopSecure.Category" /> Id.</param>
        /// <returns>A <see cref="System.Collections.Generic.List" /> of 
        /// <see cref="VidoopSecure.CategoryImage" />s.</returns>
        public List<CategoryImage> GetCategoryImages(string id)
        {
            string apiUrl = this.CreateRequestUrl("/categories/" + id + "/representative_images"); 

            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "GET", null, null);
            if (proxy.StatusCode == (int)HttpStatusCode.OK)
            {
                List<CategoryImage> categories = CategoryImage.FromImagesXml(
                    proxy.Response.GetResponseStream());
                proxy.Close();
                return categories;
            }
            else
            {
                proxy.Close();
                return null;
            }
        } 


        /// <summary>
        /// Get a randomly-selected subset of available
        /// <see cref="VidoopSecure.ImageShield" /> category IDs.
        /// </summary>
        /// <param name="count">The number of category Ids the 
        /// returned bundle should contain.</param>
        /// <param name="startsWith">A 
        /// <see cref="System.Collections.Generic.List" /> of category Id
        /// strings.</param>
        /// <returns>A <see cref="System.Collections.Generic.List" />
        /// of category Id strings representing a bundle.</returns>
        public List<string> GetRandomBundle(int count, List<string> startsWith) 
        {
            List<string> bundle = null;

            string apiUrl = this.CreateRequestUrl("/categories");

            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters.Add("count", count.ToString());

            if (startsWith != null && startsWith.Count > 0)
            {
                parameters.Add("start_with", string.Join(":", startsWith.ToArray()));
            }
            
            HttpProxy proxy = this.Manager.ApiCall(apiUrl, "GET", parameters, null);
            if (proxy.StatusCode == (int)HttpStatusCode.OK)
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(proxy.Response.GetResponseStream());
                string bundleStr = doc.GetElementsByTagName("bundle")[0].InnerText;
                bundle = new List<string>(bundleStr.Split(new char[] { ':' }));
            }

            proxy.Close();

            return bundle;
        } 
    }
}
